#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#define SPORT 9006
void read_cb(bufferevent *be, void *arg)
{
    printf("read_cb\r\n");
    char data[1024] = {0};
    memset(data,0,sizeof(data));
    int len = bufferevent_read(be,data, sizeof(data)-1);
    printf("data:%s\r\n",data);

    bufferevent_write(be, data, len);

}
void write_cb(bufferevent *be, void *arg)
{
    printf("write_cb\r\n");
}
void event_cb(bufferevent *be, short what, void *arg)
{
    printf("event_cb\r\n");
}
bufferevent_filter_result filter_in(evbuffer *s, evbuffer *d, ev_ssize_t limit,
        bufferevent_flush_mode mode, void *arg)
{
    printf("filter_in\r\n");
    char data[1024] = {0};
    memset(data,0,sizeof(data));
    int len = evbuffer_remove(s, data, sizeof(data)-1);

    evbuffer_add(d, data, len);
    return BEV_OK;
}
bufferevent_filter_result filter_out(evbuffer *s, evbuffer *d, ev_ssize_t limit,
        bufferevent_flush_mode mode, void *arg)
{
    printf("filter_out\r\n");
    char data[1024] = {0};
    memset(data,0,sizeof(data));
    int len = evbuffer_remove(s, data, sizeof(data)-1);

    evbuffer_add(d, data, len);
    printf("out:%s\r\n",data);
    return BEV_OK;
}
void listen_cb(evconnlistener *ev, evutil_socket_t s, sockaddr *a, int socklen, void *arg)
{
    //printf("listen_cb\r\n");
    event_base *base = (event_base*)arg;
    /* create bufferevent, bind bufferevent filter */
    bufferevent *bev = bufferevent_socket_new(base, s, BEV_OPT_CLOSE_ON_FREE);

    bufferevent *bev_filter = bufferevent_filter_new(bev,
            filter_in,
            filter_out,
            BEV_OPT_CLOSE_ON_FREE,
            0,
            0);
    
    bufferevent_setcb(bev_filter, read_cb, write_cb, event_cb, NULL);

    bufferevent_enable(bev_filter, EV_READ|EV_WRITE);
}

int main() {
    if(signal(SIGPIPE, SIG_IGN) == SIG_ERR){
        return 1;
    }
    event_base * base = event_base_new();
    if(base) {
        printf("event_base_new success!\r\n");
    }
    /* socket, bind, listen*/
    sockaddr_in sin;
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SPORT);
    evconnlistener *ev = evconnlistener_new_bind(base,/*base*/
                        listen_cb,
                        base,
                        LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE,
                        10,
                        (sockaddr*)&sin,
                        sizeof(sin));
    /*事件分发处理*/
    event_base_dispatch(base);
    

    evconnlistener_free(ev);
    event_base_free(base);
}